package com.istock.monitor.agent.transformer;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class AbstractApplicationContextClassWriter implements ClassRewriter ,Opcodes{

	@Override
	public boolean canRewriter(String className) {
		return "org/springframework/jca/context/ResourceAdapterApplicationContext".equals(className)||
				"org/springframework/web/context/support/AbstractRefreshableWebApplicationContext".equals(className)||
				"org/springframework/web/context/support/GenericWebApplicationContext".equals(className);
	}

	@Override
	public byte[] rewriteClass(byte[] classFileByte) {
		ClassReader cr = new ClassReader(classFileByte);
		ClassWriter cw = new ClassWriter(cr,ClassWriter.COMPUTE_FRAMES);
		cr.accept(new ApplicationTextClassAdapter(ASM5 , cw), ClassReader.SKIP_DEBUG);
		return cw.toByteArray();
	}

	class ApplicationTextClassAdapter extends ClassVisitor{

		public ApplicationTextClassAdapter(int api, ClassVisitor cv) {
			super(api, cv);
		}

		@Override
		public MethodVisitor visitMethod(int access, String name, String desc,
				String signature, String[] exceptions) {
			MethodVisitor mvb = super.visitMethod(access, name, desc, signature, exceptions);
			if (name.equals("postProcessBeanFactory") && desc.equals("(Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;)V")) {
				mvb =  new PostProcessBeanFactoryMethodVisitor(ASM5 , mvb);
			}
			return mvb;
		}
	}
	
	class PostProcessBeanFactoryMethodVisitor extends MethodVisitor{

		public PostProcessBeanFactoryMethodVisitor(int api, MethodVisitor mv) {
			super(api, mv);
		}
		public PostProcessBeanFactoryMethodVisitor(int api) {
			super(api);
		}

		@Override
		public void visitCode() {
			mv.visitCode();
			mv.visitVarInsn(ALOAD, 1);
//			mv.visitMethodInsn(INVOKEVIRTUAL, "com/istock/agent/proxy/ProxyHandlerHolder", "beforeMethod", "(Ljava/lang/Object;[Ljava/lang/Object;)V", false);
			mv.visitMethodInsn(INVOKESTATIC, "com/istock/monitor/agent/spring/SpringInjector", "registerBeanPostProcessor", "(Lorg/springframework/beans/factory/config/ConfigurableListableBeanFactory;)V", false);
			mv.visitInsn(RETURN);
			mv.visitMaxs(1, 2);
			mv.visitEnd();
		}

		@Override
		public void visitInsn(int opcode) {
//			mv.visitInsn(opcode);
		}
	}
}
